//! 节点管理模块
//! 
//! 负责集群中节点的发现、注册、健康检查和状态管理。

use crate::{Error, Result};
use super::{ClusterConfig, ClusterEvent};
use std::collections::HashMap;
use std::net::SocketAddr;
use std::time::{SystemTime, Duration};
use serde::{Serialize, Deserialize};
use tokio::sync::mpsc;

/// 节点管理器
#[derive(Debug)]
pub struct NodeManager {
    /// 集群配置
    config: ClusterConfig,
    /// 节点注册表
    nodes: HashMap<String, NodeInfo>,
    /// 事件发送器
    event_sender: Option<mpsc::UnboundedSender<ClusterEvent>>,
}

/// 节点信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeInfo {
    /// 节点ID
    pub node_id: String,
    /// 节点地址
    pub address: SocketAddr,
    /// 节点状态
    pub status: NodeStatus,
    /// 最后心跳时间
    pub last_heartbeat: SystemTime,
    /// 节点角色
    pub role: NodeRole,
    /// 节点元数据
    pub metadata: NodeMetadata,
}

/// 节点状态
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum NodeStatus {
    /// 活跃
    Active,
    /// 不可达
    Unreachable,
    /// 离线
    Offline,
    /// 加入中
    Joining,
    /// 离开中
    Leaving,
}

/// 节点角色
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum NodeRole {
    /// 领导者
    Leader,
    /// 跟随者
    Follower,
    /// 候选者
    Candidate,
}

/// 节点元数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeMetadata {
    /// 数据中心
    pub datacenter: String,
    /// 机架
    pub rack: String,
    /// 可用区
    pub availability_zone: String,
    /// 节点容量
    pub capacity: NodeCapacity,
}

/// 节点容量
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeCapacity {
    /// CPU核数
    pub cpu_cores: u32,
    /// 内存大小（字节）
    pub memory_bytes: u64,
    /// 存储大小（字节）
    pub storage_bytes: u64,
    /// 网络带宽（字节/秒）
    pub network_bandwidth_bps: u64,
}

impl NodeManager {
    /// 创建新的节点管理器
    pub fn new(config: ClusterConfig) -> Result<Self> {
        Ok(Self {
            config,
            nodes: HashMap::new(),
            event_sender: None,
        })
    }
    
    /// 启动节点管理器
    pub async fn start(&mut self) -> Result<()> {
        tracing::info!("启动节点管理器");
        
        // 注册当前节点
        self.register_self().await?;
        
        // 启动心跳检查
        self.start_heartbeat_checker().await?;
        
        tracing::info!("节点管理器启动完成");
        Ok(())
    }
    
    /// 停止节点管理器
    pub async fn stop(&mut self) -> Result<()> {
        tracing::info!("停止节点管理器");
        
        // 注销当前节点
        self.unregister_self().await?;
        
        tracing::info!("节点管理器已停止");
        Ok(())
    }
    
    /// 注册当前节点
    async fn register_self(&mut self) -> Result<()> {
        let node_info = NodeInfo {
            node_id: self.config.node_id.clone(),
            address: self.config.listen_addr,
            status: NodeStatus::Active,
            last_heartbeat: SystemTime::now(),
            role: NodeRole::Follower,
            metadata: NodeMetadata::default(),
        };
        
        self.nodes.insert(self.config.node_id.clone(), node_info);
        tracing::info!("注册当前节点: {}", self.config.node_id);
        
        Ok(())
    }
    
    /// 注销当前节点
    async fn unregister_self(&mut self) -> Result<()> {
        self.nodes.remove(&self.config.node_id);
        tracing::info!("注销当前节点: {}", self.config.node_id);
        Ok(())
    }
    
    /// 注册节点
    pub async fn register_node(&mut self, node_info: NodeInfo) -> Result<()> {
        tracing::info!("注册节点: {}", node_info.node_id);
        
        let node_id = node_info.node_id.clone();
        self.nodes.insert(node_id.clone(), node_info);
        
        // 发送节点加入事件
        if let Some(sender) = &self.event_sender {
            let _ = sender.send(ClusterEvent::NodeJoined(node_id));
        }
        
        Ok(())
    }
    
    /// 注销节点
    pub async fn unregister_node(&mut self, node_id: &str) -> Result<()> {
        tracing::info!("注销节点: {}", node_id);
        
        if self.nodes.remove(node_id).is_some() {
            // 发送节点离开事件
            if let Some(sender) = &self.event_sender {
                let _ = sender.send(ClusterEvent::NodeLeft(node_id.to_string()));
            }
        }
        
        Ok(())
    }
    
    /// 更新节点心跳
    pub async fn update_heartbeat(&mut self, node_id: &str) -> Result<()> {
        if let Some(node) = self.nodes.get_mut(node_id) {
            node.last_heartbeat = SystemTime::now();
            node.status = NodeStatus::Active;
            tracing::debug!("更新节点心跳: {}", node_id);
        }
        Ok(())
    }
    
    /// 获取节点信息
    pub fn get_node(&self, node_id: &str) -> Option<&NodeInfo> {
        self.nodes.get(node_id)
    }
    
    /// 获取所有节点
    pub fn get_all_nodes(&self) -> Vec<&NodeInfo> {
        self.nodes.values().collect()
    }
    
    /// 获取活跃节点
    pub fn get_active_nodes(&self) -> Vec<&NodeInfo> {
        self.nodes
            .values()
            .filter(|node| node.status == NodeStatus::Active)
            .collect()
    }
    
    /// 获取领导者节点
    pub fn get_leader(&self) -> Option<&NodeInfo> {
        self.nodes
            .values()
            .find(|node| node.role == NodeRole::Leader)
    }
    
    /// 设置节点角色
    pub async fn set_node_role(&mut self, node_id: &str, role: NodeRole) -> Result<()> {
        if let Some(node) = self.nodes.get_mut(node_id) {
            node.role = role.clone();
            tracing::info!("设置节点角色: {} -> {:?}", node_id, role);
            
            // 如果设置为领导者，发送领导者变更事件
            if role == NodeRole::Leader {
                if let Some(sender) = &self.event_sender {
                    let _ = sender.send(ClusterEvent::LeaderChanged(Some(node_id.to_string())));
                }
            }
        }
        Ok(())
    }
    
    /// 启动心跳检查器
    async fn start_heartbeat_checker(&self) -> Result<()> {
        tracing::debug!("启动心跳检查器");
        
        // 简化实现：实际需要启动后台任务定期检查心跳
        // 这里只是记录日志
        
        Ok(())
    }
    
    /// 检查节点健康状态
    pub async fn check_node_health(&mut self) -> Result<()> {
        let now = SystemTime::now();
        let timeout = Duration::from_millis(self.config.heartbeat_interval_ms * 3);
        
        let mut unhealthy_nodes = Vec::new();
        
        for (node_id, node) in &mut self.nodes {
            if let Ok(elapsed) = now.duration_since(node.last_heartbeat) {
                if elapsed > timeout && node.status == NodeStatus::Active {
                    node.status = NodeStatus::Unreachable;
                    unhealthy_nodes.push(node_id.clone());
                    tracing::warn!("节点不可达: {}", node_id);
                }
            }
        }
        
        // 处理不健康的节点
        for node_id in unhealthy_nodes {
            if let Some(sender) = &self.event_sender {
                let _ = sender.send(ClusterEvent::NodeLeft(node_id));
            }
        }
        
        Ok(())
    }
    
    /// 设置事件发送器
    pub fn set_event_sender(&mut self, sender: mpsc::UnboundedSender<ClusterEvent>) {
        self.event_sender = Some(sender);
    }
}

impl Default for NodeMetadata {
    fn default() -> Self {
        Self {
            datacenter: "dc1".to_string(),
            rack: "rack1".to_string(),
            availability_zone: "az1".to_string(),
            capacity: NodeCapacity::default(),
        }
    }
}

impl Default for NodeCapacity {
    fn default() -> Self {
        Self {
            cpu_cores: 4,
            memory_bytes: 8 * 1024 * 1024 * 1024, // 8GB
            storage_bytes: 100 * 1024 * 1024 * 1024, // 100GB
            network_bandwidth_bps: 1024 * 1024 * 1024, // 1Gbps
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_node_manager_creation() {
        let config = ClusterConfig::default();
        let node_manager = NodeManager::new(config).unwrap();
        
        assert_eq!(node_manager.nodes.len(), 0);
        assert!(node_manager.event_sender.is_none());
    }
    
    #[tokio::test]
    async fn test_node_registration() {
        let config = ClusterConfig::default();
        let mut node_manager = NodeManager::new(config).unwrap();
        
        let node_info = NodeInfo {
            node_id: "test-node".to_string(),
            address: "127.0.0.1:8000".parse().unwrap(),
            status: NodeStatus::Active,
            last_heartbeat: SystemTime::now(),
            role: NodeRole::Follower,
            metadata: NodeMetadata::default(),
        };
        
        node_manager.register_node(node_info).await.unwrap();
        assert_eq!(node_manager.nodes.len(), 1);
        
        let registered_node = node_manager.get_node("test-node").unwrap();
        assert_eq!(registered_node.node_id, "test-node");
        assert_eq!(registered_node.status, NodeStatus::Active);
    }
    
    #[tokio::test]
    async fn test_node_role_management() {
        let config = ClusterConfig::default();
        let mut node_manager = NodeManager::new(config).unwrap();
        
        // 注册节点
        let node_info = NodeInfo {
            node_id: "leader-node".to_string(),
            address: "127.0.0.1:8000".parse().unwrap(),
            status: NodeStatus::Active,
            last_heartbeat: SystemTime::now(),
            role: NodeRole::Follower,
            metadata: NodeMetadata::default(),
        };
        
        node_manager.register_node(node_info).await.unwrap();
        
        // 设置为领导者
        node_manager.set_node_role("leader-node", NodeRole::Leader).await.unwrap();
        
        let leader = node_manager.get_leader().unwrap();
        assert_eq!(leader.node_id, "leader-node");
        assert_eq!(leader.role, NodeRole::Leader);
    }
}
